#include "stdafx.h"
#include "LoopBuffer.h"

CLoopBuffer::CLoopBuffer(void)
{
	m_pHead = NULL;
	m_pTail = NULL;
	m_pRead = NULL;
	m_pWrite = NULL;

}

CLoopBuffer::~CLoopBuffer(void)
{
	if(m_pHead != NULL)
		delete[] m_pHead;

	m_pHead = NULL;
	m_pTail = NULL;
	m_pRead = NULL;
	m_pWrite = NULL;
}

bool CLoopBuffer::Init(int nSize)
{
	m_pHead = new char[nSize];

	if(m_pHead == NULL)
		return false;

	memset(m_pHead, 0, nSize);

	m_pWrite = m_pHead;
	m_pRead = m_pHead;
	m_pTail = m_pHead + nSize;

	return true;
}

bool CLoopBuffer::Read(char* pOutBuff, int nSize)
{
	if(m_pRead == m_pWrite)
		return false;

	if(m_pRead < m_pWrite)
	{
		if(nSize >= m_pWrite - m_pRead)
			return false;

		memcpy(pOutBuff, m_pRead, nSize);
		m_pRead += nSize;

		return true;
	}

	int nCaps = m_pTail - m_pRead;

	if(nSize <= nCaps)
	{
		memcpy(pOutBuff, m_pRead, nSize);
		m_pRead += nSize;
		return true;
	}

	int nRemain = nSize - nCaps;
	if(m_pHead + nRemain >= m_pWrite)
		return false;

	memcpy(pOutBuff, m_pRead, nCaps);
	memcpy(pOutBuff + nCaps, m_pHead, nRemain);

	m_pRead = m_pHead + nRemain;

	return true;
}

bool CLoopBuffer::Write(const char* pData, int nSize)
{
	if(m_pWrite < m_pRead)
	{
		if(nSize >= m_pRead - m_pWrite)
			return false;

		memcpy(m_pWrite, pData, nSize);
		m_pWrite += nSize;

		return true;
	}

	int nCaps = m_pTail - m_pWrite;

	if(nSize <= nCaps)
	{
		memcpy(m_pWrite, pData, nSize);
		m_pWrite += nSize;
		return true;
	}

	int nRemain = nSize - nCaps;
	if(m_pHead + nRemain >= m_pRead)
		return false;

	memcpy(m_pWrite, pData, nCaps);
	memcpy(m_pHead, pData + nCaps, nRemain);

	m_pWrite = m_pHead + nRemain;

	return true;
}

int CLoopBuffer::PreRead(char cVal)
{
	char* p = m_pRead;
	int nRet = 1;

	while(true)
	{
		if(p >= m_pTail)
			p = m_pHead;

		if(p == m_pWrite)
			return 0;

		if(*p == cVal)
			return nRet;

		p++;
		nRet++;
	}

	return 0;
}
